【PHP】クラス変数(static) - 同じクラスのオブジェクト間で共通の変数

【PHP】クラス変数(static) - 同じクラスのオブジェクト間で共通の変数

クラスにはクラス変数と呼ぶ変数があります。

クラス変数はクラスレベルの変数で、同じクラスのオブジェクト間で共通の変数になります。

ここでは、クラス変数について解説します。

検証環境

クラス変数

クラス変数は“クラスレベルの変数”です。

クラスに紐づく変数のため、フィールドとは異なり、オブジェクトを生成しなくても使用可能な変数になります。

また、オブジェクトのメソッドからクラス変数を使うことができ、同じクラスのオブジェクト間でクラス変数は共通の変数です。

クラス変数は“クラスプロパティ”や“クラスフィールド”などと呼ぶ場合があります。

クラス変数の定義

クラス変数を使うには定義が必要です。

基本構文

class クラス名 {
    アクセス修飾子 static $クラス変数名;
}

クラス変数はstaticキーワードをアクセス修飾子と変数の間に記述します。

サンプル

<?php

// 人間クラス
class Person {
    
    ___ih_hl_start
    public static $greeting;
    ___ih_hl_end
    
}

?>
$ php sample.php
$

6行目がクラス変数$greetingの定義です。

値の取得

クラスを経由して、クラス変数の値を取得します。

基本構文

クラス名::クラス変数

クラス名とクラス変数をダブルコロン(::)で繋げて記述します。

サンプル

<?php

// 人間クラス
class Person {
    
    public static $greeting;
    
}

___ih_hl_start
var_dump(Person::$greeting);
___ih_hl_end

?>
$ php sample.php
NULL

10行目のPerson::$greetingがクラス変数のアクセスです。

Personクラスの$greetingにアクセスし、値を取得しています。

$greetingは値が未設定のため、var_dump関数の出力結果はNULLになります。

値の記憶

クラス変数に値を記憶するにはクラスを経由します。

基本構文

クラス名::クラス変数 = 値

クラス変数に値を記憶するには、代入演算子(=)を使います。

クラス変数の指定方法は値の取得と同様でダブルコロン(::)でクラス名とクラス変数をつなげて記述します。

サンプル

<?php

// 人間クラス
class Person {
    
    public static $greeting;
    
}

___ih_hl_start
Person::$greeting = 'Hello';
___ih_hl_end

var_dump(Person::$greeting);

?>
$ php sample.php
This is Person class.

10行目がクラス変数に値を記憶するコードです。

$greetingに文字列を代入しいます。

var_dump関数の出力結果から、正常に記憶できていることが分かります。

オブジェクトの共通変数

上述したとおり、クラス変数は同じクラスのオブジェクト間で共通の変数です。

次のように異なるオブジェクトのメソッドからアクセスした場合でも同じ変数にアクセスします。

<?php

// 人間クラス
class Person {
    
    public static $greeting;
    
    public $name;
    
    public function __construct( $n ) {
        $this->name = $n;
    }
    
    public function message() {
        ___ih_hl_start
        echo Person::$greeting . "\n";
        ___ih_hl_end
        echo 'My name is ' . $this->name . ".\n";
    }
    
}

$person1 = new Person('TANAKA');
$person2 = new Person('SUZUKI');

___ih_hl_start
Person::$greeting = 'Hello.';
___ih_hl_end
$person1->message();
$person2->message();

___ih_hl_start
Person::$greeting = 'Hey!';
___ih_hl_end
$person1->message();
$person2->message();

?>
$ php sample.php
Hello.
My name is TANAKA.
Hello.
My name is SUZUKI.
Hey!
My name is TANAKA.
Hey!
My name is SUZUKI.

15行目を含む、messageメソッドは自身のクラス変数にアクセスします。

21〜22行目でPersonクラスのオブジェクトを2つ生成し、24行目で$greetingに値を代入しています。

直後の各オブジェクトのmessageメソッドの出力から、$greetingはクラスで共通の変数のため、同じ値を取得したことが分かります。

また、28行目で$greetingの値を更新し、各オブジェクトのmessageメソッドを再度呼び出していますが、どちらも値が変わっています。

演習問題

問題1

次の実行結果になる車クラスを扱うプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 車クラスを作成する
  • 車クラスのフィールドはナンバー、色、乗車人数とする
  • 車クラスのインスタンスの初期値はコンストラクタで設定する
  • 車情報を出力するinfoメソッドを作成する
  • タイヤ数はクラス変数とする
===== 車情報 =====
ナンバー : 1234
色    : 紺色
乗車人数 : 5人
タイヤ数 : 4個
===== 車情報 =====
ナンバー : 0987
色    : 赤
乗車人数 : 2人
タイヤ数 : 4個

問題2

次の実行結果になる家クラスを扱うプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 家クラスを作成する
  • 家クラスのフィールドは面積(単位:畳)とする
  • 家クラスのインスタンスを3つ生成し、各面積(畳)は次の通りとする
    1つ目 : 6
    2つ目 : 14
    3つ目 : 30
  • 家クラスのインスタンスの初期値はコンストラクタで設定する
  • 畳の高さ(1.82m)と横幅(0.91m)を記憶するクラス変数を定義する
  • クラス変数を使って家の面積(平方メートル)を出力するareaメソッドを作成する
面積 : 9.9372平方メートル
面積 : 23.1868平方メートル
面積 : 49.686平方メートル